package com.alan.shiro.api.token.manager;

import com.alan.shiro.api.token.StatelessToken;
import com.alan.shiro.api.token.helper.UserTokenOperHelper;
import com.nimbusds.jose.JOSEException;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

/**
 * @Auther: Alan liu
 * @Date: 2018/12/13 10:57
 * @Description: AbstractTokenManager
 */
@Slf4j
public abstract class AbstractTokenManager implements TokenManager{
    /**
     * 失效时间 单位秒
     */
    @Setter
    @Getter
    protected long expirateTime;

    protected String userTokenPrefix ="token_";

    /**
     * 模拟缓存操作token
     */
    @Setter
    @Getter
    protected UserTokenOperHelper userTokenOperHelper;


    @Override
    public StatelessToken createToken(String userCode) throws Exception {
        StatelessToken tokenModel = null;
        String token = userTokenOperHelper.getUserToken(userTokenPrefix+userCode);
        if(StringUtils.isEmpty(token)){
            token = createStringToken(userCode);
        }
        userTokenOperHelper.updateUserToken(userTokenPrefix+userCode, token, expirateTime);
        tokenModel = new StatelessToken(Long.valueOf(userCode), token);
        return tokenModel;
    }

    public abstract String createStringToken(String userCode) throws JOSEException;

    protected boolean checkMemoryToken(StatelessToken statelessToken) {
        if(statelessToken == null){
            return false;
        }
        Long userId = (Long)statelessToken.getPrincipal();
        String credentials = (String)statelessToken.getCredentials();
        String token = userTokenOperHelper.getUserToken(userTokenPrefix+userId);
        if (token == null || !credentials.equals(token)) {
            return false;
        }
        return true;
    }

    @Override
    public StatelessToken getToken(String authentication){
        if(StringUtils.isEmpty(authentication)){
            return null;
        }
        String[] au = authentication.split("_");
        if (au.length <=1) {
            return null;
        }
        String userCode = au[0];
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i < au.length; i++) {
            sb.append(au[i]);
            if(i<au.length-1){
                sb.append("_");
            }
        }
        return new StatelessToken(Long.valueOf(userCode), sb.toString());
    }

    @Override
    public boolean check(String authentication) {
        StatelessToken token = getToken(authentication);
        if(token == null){
            return false;
        }
        return checkMemoryToken(token);
    }

    @Override
    public void deleteToken(String userCode) {
        userTokenOperHelper.deleteUserToken(userTokenPrefix+userCode);
    }



    //public LoginFlagOperHelper getLoginFlagOperHelper() {
    //	return loginFlagOperHelper;
    //}

    //public void setLoginFlagOperHelper(LoginFlagOperHelper loginFlagOperHelper) {
    //	this.loginFlagOperHelper = loginFlagOperHelper;
    //}

}
